package com.redshark.wmm.Bluetooth;

import java.util.LinkedList;

import com.jjoe64.graphview.GraphView.GraphViewData;
import com.jjoe64.graphview.GraphViewSeries;
import com.redshark.wmm.MeasurementProcessing.*;

public class ScopeMessage extends BluetoothMessage {
	private static final double TIME_PER_MEASUREMENT = .176;
	private final int NUM_DATAS = 256;
	private GraphViewData[] graphViewData = new GraphViewData[NUM_DATAS];
	private int graphViewDataIndex = 0;
	private double graphViewDataTime = 0;
	private RMSCalculator rmsCalc;
	
	private LinkedList<Double> holdingZone = new LinkedList<Double>();
	
	private double maxValue = Double.NEGATIVE_INFINITY;
	private double minValue = Double.POSITIVE_INFINITY;
	
	private int trigger;
	
	public final static int VOLTAGE = 0;
	public final static int CURRENT = 1;

	public ScopeMessage(int type, int command, int messageNum) {
		super(type, command, messageNum);

		rmsCalc = new RMSCalculator();
	}

	public void addData(int data) throws ScopeMessageException {
		double d;
		
		if(rmsCalc.count() == 0){
			trigger = data;
		}
		
		//Check for voltage scope
		if (getCommand() > 70 && getCommand() < 76) {
			d = VoltageProcessor.processMeasurement(data, getCommand() - 71);
		}

		else if (getCommand() == 76) {
			d = CurrentProcessor.processMeasurement(data, CurrentProcessor.LOW_CURRENT);
		} else if (getCommand() == 77) {
			d = CurrentProcessor.processMeasurement(data, CurrentProcessor.HIGH_CURRENT);
		} else {
			throw new ScopeMessageException("Invalid Command");
		}

		//Add it to the rmsCalc
		if(data < trigger-5 || data > trigger+5 ){
			holdingZone.add(d);
		}
		else{
			for(double num : holdingZone){
				rmsCalc.add(num);

			}
			holdingZone.clear();
			rmsCalc.add(d);
		}
		
		//Store it in the Graphviewdata
		graphViewData[graphViewDataIndex++] = new GraphViewData(
				graphViewDataTime, d);
		
		
		graphViewDataTime += TIME_PER_MEASUREMENT;
		
		//Store the max and min values we have seen
		if(d>maxValue){
			maxValue = d;
		}
		if(d<minValue){
			minValue = d;
		}
		

	}

	public double getMaxValue() {
		return maxValue;
	}

	public double getMinValue() {
		return minValue;
	}

	public GraphViewSeries getGraphViewSeries() {
		return new GraphViewSeries(graphViewData);
	}

	public double getRMS() {
		return rmsCalc.calculateRMS();
	}
	
	public int getCmdType(){
		if(getCommand() > 70 && getCommand() < 76){
			return VOLTAGE;
		}
		else if(getCommand() == 75 || getCommand()==76){
			return CURRENT;
		}
		return 0;
	}

	public class ScopeMessageException extends Exception {

		private static final long serialVersionUID = 6471038150723179854L;

		public ScopeMessageException(String message) {
			super(message);
		}

		public ScopeMessageException(String message, Throwable throwable) {
			super(message, throwable);
		}

	}

}
